/*--- SOUNDEX.C ---------------------------- Listing 4-7 -------
*   Will generate the soundex code for a name or word.
*
*   Usage: int Soundex ( char *name, char *soundex_code )
*
*   if DRIVER is #defined a driver routine is compiled.
*-------------------------------------------------------------*/

#include <ctype.h>
#include <string.h>

#define DRIVER 1

int Soundex ( const char *str, char *soundex_out )
{

#define SOUNDEX_ERR 0
#define SOUNDEX_OK  1

    static const char table[] =

      /* ABCDEFGHIJKLMNOPQRSTUVWXYZ */
        "01230120022455012623010202";

    int count = 0;                  /* Valid code letters done */
    char this_char, prev_char;      /* Current and previous    */
    char code [5];                  /* will hold Soundex code  */

    strcpy ( code, "    " );        /* Initialize string       */

    this_char = toupper ( *str );   /* The first character is  */
    if ( isalpha ( this_char ))     /* preserved albeit as     */
    {                               /* uppercase.              */
        code[0] = this_char;
        count = 1;
        str += 1;
    }
    else
        return ( SOUNDEX_ERR );

    prev_char = ' ';               /* previous char empty now  */

    while ( count < 4 && isalpha ( *str ))
    {
        char c;

        this_char = toupper ( *str );
        c = table[this_char - 'A'];

       /*--------------------------------------------------------
        *  Remove 0's and repeated sequences from output
        *  and then insert the next character into the string.
        *------------------------------------------------------*/

        if ( c != prev_char && c != '0' )
        {
            code[count++] = c;
            prev_char = c;
        }
        str += 1;
    }

    /* Next, if it's neither '/0' nor a letter, it's an error */

    if ( *str != '\0' && ! ( isalpha( *str )))
        return ( SOUNDEX_ERR );
    else
    {
        strcpy ( soundex_out, code );
        return ( SOUNDEX_OK );
    }
}

#ifdef DRIVER         /* Driver to demo soundex results */

#include <stdio.h>
#include <stdlib.h>

int main ( int argc, char *argv[] )
{
    char code[5];

    if ( argc != 2 )
    {
        fprintf ( stderr,
                    "Error! Usage: soundex word-to-code\n" );
        return ( EXIT_FAILURE );
    }

    if ( Soundex ( argv[1], code) == 0 )
        printf ("%s is not a valid name or word\n", argv[1] );
    else
        printf ( "Soundex for %s is %s\n", argv[1], code );

    return ( EXIT_SUCCESS );
}
#endif
